'use client';

import type { IDifference } from '@/interfaces';
import { sendMessage } from '@/services/api';
import { useMutation } from '@tanstack/react-query';
import {
  type ChangeEvent,
  type FormEvent,
  useEffect,
  useRef,
  useState,
} from 'react';
import diff from 'microdiff';
import useToast from '@/hooks/useToast';
import { clearFormData, getDiffData, isNum } from '@/lib/tool';
import dynamic from 'next/dynamic';
import EditorSuspense from '@/app/[locale]/posts/[id]/edit/editor/load';
import {
  handleEditorBeforeunload,
  handleEditorSave,
  handleEditorStatusChanges,
} from '@/lib/editor/handle';
import { getEditorContentHtml, setEditorContentHtml } from '@/lib/editor';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import Box from '@/app/[locale]/admin/common/box';
import type { TMessageRange } from '@/types';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

const DynamicEditor: any = dynamic(
  () => import('../../../posts/[id]/edit/editor/editor'),
  {
    loading: () => <EditorSuspense />,
    ssr: false,
  },
);

export default function CreateMessageAdminPage({
  source,
  translatedFields,
}: {
  source?: any;
  translatedFields: PrefixedTTranslatedFields<'messageAdminPage'>;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    name: string;
    content: string;
    messageRange: TMessageRange;
    businessId?: number;
    businessName?: string;
    businessRemark?: string;
    receiver?: number;
  }>({
    name: '',
    content: '',
    messageRange: 'USER',
    businessName: '',
    businessRemark: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const editorRef = useRef<any>();
  const [isActive, setIsActive] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const isDirty = useRef(false);
  const isLoadingSave = useRef(false);
  const [isReady, setIsReady] = useState(false);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const sendMessageMutation = useMutation(sendMessage);

  useEffect(() => {
    const diffData = diff(
      {
        name: '',
        content: '',
        messageRange: 'USER',
        businessName: '',
        businessRemark: '',
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form]);
  useEffect(() => {
    const selector = document.querySelector('.yw-navbar-layout');
    if (selector) {
      selector.classList.remove('sticky-top');
    }

    return () => {
      if (selector) {
        selector.classList.add('sticky-top');
      }
    };
  }, []);

  function getContent(data?: any) {
    return getEditorContentHtml(editorRef.current, data);
  }

  async function onClickSave() {
    const editor = editorRef.current;
    if (!editor) {
      return;
    }

    await handleEditorSave({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
      callback: onClickSaveCore,
    });
  }

  async function onClickSaveCore({
    data,
    reset,
  }: {
    data: string;
    reset: () => void;
  }) {
    try {
      isLoadingSave.current = true;

      checkForm();

      const _data = getDiffData(differenceData);
      const content = getContent(data);
      await sendMessageMutation.mutateAsync({
        data: {
          ...(_data as any),
          content,
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.saveCompleted,
      });
    } catch (e) {
      sendMessageMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      isLoadingSave.current = false;
      reset();
      setForm(clearFormData(form));
      setDifferenceData([]);
    }
  }

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    e.stopPropagation();
    await onClickSave();
  }

  function checkForm() {
    const { name, messageRange, receiver, businessId } = form;

    if (!name) {
      throw translatedFields.tip.nameRequired;
    }

    if (businessId !== null && businessId !== undefined && !isNum(businessId)) {
      throw translatedFields.tip.businessIdInvalidFormat;
    }

    if (!messageRange) {
      throw translatedFields.tip.messageRangeRequired;
    } else if (messageRange === 'USER') {
      if (!isNum(receiver)) {
        throw translatedFields.tip.receiverRequired;
      }
    }

    if (!getContent()) {
      throw translatedFields.tip.contentRequired;
    }
  }

  function onChange(
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'businessId') {
      if (isNum(value)) {
        setForm({ ...form, businessId: parseInt(value) });
      } else {
        setForm({ ...form, businessId: undefined });
      }
    } else if (name === 'receiver') {
      if (isNum(value)) {
        setForm({ ...form, receiver: parseInt(value) });
      } else {
        setForm({ ...form, receiver: undefined });
      }
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  function onReady({ editor }: { editor: any }) {
    handleEditorStatusChanges({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
    });
    handleEditorBeforeunload({ editor });
    setEditorContentHtml(editor, form.content);
    editorRef.current = editor;
    setIsReady(true);
  }

  return (
    <Box>
      <div className="card">
        <div className="card-body">
          <form onSubmit={onSubmit} className="vstack gap-4">
            <div className="row">
              <div className="col">
                <div>
                  <label className="form-label">
                    {translatedFields.properties.name}
                  </label>
                  <textarea
                    rows={1}
                    name="name"
                    value={form.name}
                    onChange={onChange}
                    className="form-control"
                    aria-describedby="name"
                  />
                </div>
              </div>
              <div className="col">
                <div>
                  <label className="form-label">
                    {translatedFields.properties.messageRange}
                  </label>
                  <select
                    name="messageRange"
                    value={form.messageRange}
                    onChange={onChange}
                    className="form-select"
                    aria-describedby="messageRange"
                  >
                    {['USER', 'ALL'].map((item) => {
                      return (
                        <option key={item} value={item}>
                          {(translatedFields as any).enums.messageRange[item]}
                        </option>
                      );
                    })}
                  </select>
                </div>
              </div>
            </div>

            {form.messageRange === 'USER' && (
              <div>
                <label className="form-label">
                  {translatedFields.properties.receiver}
                </label>
                <input
                  type="text"
                  name="receiver"
                  value={form.receiver ?? ''}
                  onChange={onChange}
                  className="form-control"
                  aria-describedby="receiver"
                />
              </div>
            )}

            <div className="row">
              <div className="col">
                <div>
                  <label className="form-label">
                    {translatedFields.properties.businessId}
                  </label>
                  <input
                    type="text"
                    name="businessId"
                    value={form.businessId ?? ''}
                    onChange={onChange}
                    className="form-control"
                    aria-describedby="businessId"
                  />
                </div>
              </div>
              <div className="col">
                <div>
                  <label className="form-label">
                    {translatedFields.properties.businessName}
                  </label>
                  <input
                    type="text"
                    name="businessName"
                    value={form.businessName}
                    onChange={onChange}
                    className="form-control"
                    aria-describedby="businessName"
                  />
                </div>
              </div>
            </div>

            <div>
              <label className="form-label">
                {translatedFields.properties.businessRemark}
              </label>
              <input
                type="text"
                name="businessRemark"
                value={form.businessRemark}
                onChange={onChange}
                className="form-control"
                aria-describedby="businessRemark"
              />
            </div>

            <div>
              <label className="form-label">
                {translatedFields.properties.content}
              </label>
              <DynamicEditor type="message" onReadyCallback={onReady} />
            </div>

            <button
              type="submit"
              disabled={sendMessageMutation.isLoading}
              className="btn btn-primary col col-lg-2 mt-4"
            >
              {sendMessageMutation.isLoading && <Spinner classs="me-2" />}
              {translatedFields.operate.save}
            </button>
          </form>
        </div>
      </div>
    </Box>
  );
}
